from django.db import DatabaseError
from django.shortcuts import render

# Create your views here.
# 导入:
from QQLoginTool.QQtool import OAuthQQ
from django.conf import settings
from django import http
from django.views import View
from rest_framework.views import APIView
from rest_framework.response import Response
from django.contrib.auth import login
import re, json
from apps.oauth.models import OAuthQQUser
from django_redis import get_redis_connection
from apps.users.models import User


class QQURLView(APIView):
    """提供QQ登录页面网址"""

    def get(self, request):
        # next 表示从哪个页面进入到的登录页面
        # 将来登录成功后，就自动回到那个页面
        next = request.query_params.get('next')

        # 获取 QQ 登录页面网址
        # 创建 OAuthQQ 类的对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,
                        state=next)

        # 调用对象的获取 qq 地址方法
        login_url = oauth.get_qq_url()

        # 返回登录地址
        return Response({'code': 0, 'errmsg': 'OK', 'login_url': login_url})


class QQUserView(APIView):
    def get(self, request):
        code = request.query_params.get('code')
        if not code:
            return Response({'code': 400, 'errmsg': '缺少code'})
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI)
        try:
            access_token = oauth.get_access_token(code)
            openid = oauth.get_open_id(access_token)
        except Exception as e:
            return Response({'code': 400, 'errmsg': 'oauth2.0认证失败, 即获取qq信息失败'})
        try:
            oauth_qq = OAuthQQUser.objects.get(openid=openid)
        except:
            from meiduo_mall.utils.secret import SecretOauth
            access_token = SecretOauth().dumps({'openid': openid})
            return Response({'code': 300, 'errmsg': 'ok', 'access_token': access_token})
        else:
            user = oauth_qq.user
            login(request, user)
            response = Response({'code': 0, 'errmsg': 'ok'})
            response.set_cookie('username', user.username, max_age=3600 * 24 * 14)
            return response

    def post(self, request):
        data_dict = json.loads(request.body.decode())
        mobile = data_dict.get('mobile')
        password = data_dict.get('password')
        sms_code_client = data_dict.get('sms_code')
        access_token = data_dict.get('access_token')
        if not all([mobile, password, sms_code_client, access_token]):
            return Response({'code': 400, 'errmsg': '缺少必传参数'})
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return Response({'code': 400, 'errmsg': '手机号格式错误'})
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return Response({'code': 400, 'errmsg': '密码格式错误'})
        redis_conn = get_redis_connection('verify_code')
        sms_code_server = redis_conn.get('sms_%s' % mobile)
        if sms_code_server is None:
            return Response({'code': 400, 'errmsg': '验证码过期'})
        if sms_code_client != sms_code_server.decode():
            return Response({'code': 400, 'errmsg': '验证码错误'})
        from meiduo_mall.utils.secret import SecretOauth
        openid = SecretOauth().loads(access_token).get('openid')
        if not openid:
            return Response({'code': 400, 'errmsg': 'openid获取失败'})
        try:
            user = User.objects.get(mobile=mobile)
        except:
            user = User.objects.create_user(username=mobile, mobile=mobile, password=password)
        else:
            if not user.check_password(password):
                return Response({'code': 400, 'errmsg': '密码错误'})
        try:
            OAuthQQUser.objects.create(user=user, openid=openid)
        except:
            return Response({'code': 400, 'errmsg': '保存失败'})
        login(request, user)
        response = Response({'code': 0, 'errmsg': 'ok'})
        response.set_cookie('username', user.username, max_age=3600 * 24 * 14)
        return response
